
package com.baseframe.auth.support;


import com.baseframe.auth.entity.BaseUserDetails;
import com.baseframe.auth.utils.TokenUtil;
import com.baseframe.jwt.props.BaseJwtProperties;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.HashMap;
import java.util.Map;

/**
 * jwt返回参数增强
 *增强令牌
 *
 */
/**
 * 这段代码是一个名为BaseJwtTokenEnhancer的类，实现了TokenEnhancer接口。它用于在生成JWT令牌时对令牌进行增强。
 *
 * 这个类有两个成员变量：jwtAccessTokenConverter和baseJwtProperties，分别表示JWT的访问令牌转换器和基本的JWT属性。
 *
 * 类中实现了TokenEnhancer接口的enhance方法，该方法接收OAuth2AccessToken和OAuth2Authentication参数，用于对令牌进行增强。
 *
 * 首先，从OAuth2Authentication中获取用户认证的principal，该Principal对象应该是BaseUserDetails类型。
 *
 * 然后，创建一个空的HashMap作为额外的信息。将用户ID、角色ID和其他详情信息放入info中。
 *
 * 接下来，将额外的信息设置到OAuth2AccessToken对象中，使用强制类型转换将OAuth2AccessToken转换为DefaultOAuth2AccessToken，
 * 然后使用setAdditionalInformation方法设置额外的信息。
 *
 * 再接下来，调用jwtAccessTokenConverter的enhance方法对accessToken进行增强，获取增强后的令牌对象。
 *
 * 接下来，获取并记录令牌的过期时间、访问令牌和刷新令牌的值。
 *
 * 最后，根据baseJwtProperties的配置判断是否支持多人在线，并将令牌加载到Redis中，调用TokenUtil.addToken2Redis方法实现。
 *
 * 最终，返回增强后的accessToken对象。
 *
 * 总的来说，这段代码定义了一个类BaseJwtTokenEnhancer，实现了TokenEnhancer接口，用于对JWT令牌进行增强。它将用户的一些附加信息
 * 添加到令牌中，并将令牌加载到Redis中。*/
@AllArgsConstructor
public class BaseJwtTokenEnhancer implements TokenEnhancer {

	private final JwtAccessTokenConverter jwtAccessTokenConverter;
	private final   BaseJwtProperties baseJwtProperties;

	@Override
	public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
		BaseUserDetails principal = (BaseUserDetails) authentication.getUserAuthentication().getPrincipal();

		//token参数增强
		Map<String, Object> info = new HashMap<>(16);
		info.put(TokenUtil.USER_ID, principal.getUserId());
		info.put(TokenUtil.ROLE_ID,principal.getRoleId());
		info.put(TokenUtil.DETAILS,principal.getDetails());
		((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);

		//获取令牌并且将令牌加载到redis中
		OAuth2AccessToken oAuth2AccessToken = jwtAccessTokenConverter.enhance(accessToken, authentication);
		int expires = accessToken.getExpiresIn();
		String accessTokenValue = oAuth2AccessToken.getValue();
		String refreshTokenValue = oAuth2AccessToken.getRefreshToken().getValue();

		//todo 判断是否支持多人在线
		TokenUtil.addToken2Redis(accessTokenValue,refreshTokenValue,expires,baseJwtProperties.getSingle());


		return accessToken;
	}
}
